<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>learning python学习心得 &mdash; python学习笔记</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <script type="text/javascript" src="_static/translations.js"></script>
    <link rel="top" title="python学习笔记" href="index.html" />
    <link rel="next" title="python的缺点" href="disadvantage.html" />
    <link rel="prev" title="python一些重要但不熟悉的语法" href="syntax.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="disadvantage.html" title="python的缺点"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="syntax.html" title="python一些重要但不熟悉的语法"
             accesskey="P">上一页</a> |</li>
        <li><a href="index.html">python学习笔记</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="learning-python">
<h1>learning python学习心得<a class="headerlink" href="#learning-python" title="永久链接至标题">¶</a></h1>
<div class="section" id="id1">
<h2>到主页的链接<a class="headerlink" href="#id1" title="永久链接至标题">¶</a></h2>
<blockquote>
<p><a class="reference external" href="http://learning-notebook.appspot.com">回到主页</a></p>
<p>注意此处回到的是最初始页面，即 <em>http://learning-notebook.appspot.com</em></p>
</blockquote>
</div>
<div class="section" id="id3">
<h2>关于learning python<a class="headerlink" href="#id3" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p><a class="footnote-reference" href="#id5" id="id4">[1]</a> <em>learning python</em> 是亚马逊评价很高的一本书,讲得比较细致和全面,要好好学习.</p>
<p class="last">下面引用的页码都是pdf中的页码.</p>
</div>
</div>
<div class="section" id="import">
<span id="index-0"></span><h2>关于import<a class="headerlink" href="#import" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>p91,import一个module时发生的动作有:找到导入的文件,编译为字节码(byte code),运行生成的字节码.因而,Python的设计使得导入的行为只能执行一次所导入的代码(即使有多次导入行为).如:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">testprint</span>
<span class="c">#假设testprint module中有一个print语句,此时会输出print后的字符串</span>
<span class="c"># do some thing</span>
<span class="kn">import</span> <span class="nn">testprint</span>    <span class="c">#此时则不会输出</span>
</pre></div>
</div>
<p>如果真要使其在当前程序中执行导入的文件,则须使用 <tt class="docutils literal"><span class="pre">reload(moduleName)</span></tt></p>
<p class="last">同样可以使用 <tt class="docutils literal"><span class="pre">execfile('module.py')</span></tt> 来执行一个文件,与import不同的是,它没有导入模块,它只是 <strong>将module.py中的代码拷贝到执行execfile处</strong>. 因此它有覆盖当前变量的可能.</p>
</div>
<table class="docutils footnote" frame="void" id="id5" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id4">[1]</a></td><td>learning python 3rd Edition</td></tr>
</tbody>
</table>
</div>
<div class="section" id="python-type-hierarchies">
<h2>python类型继承关系(type hierarchies)<a class="headerlink" href="#python-type-hierarchies" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">python中的继承关系图.</p>
</div>
<img alt="_images/type-hierarchies.JPG" src="_images/type-hierarchies.JPG" style="width: 700px; height: 800px;" />
</div>
<div class="section" id="python">
<h2>python中的函数<a class="headerlink" href="#python" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>p346.</p>
<ul class="simple">
<li>def是可执行的代码.即是一个 <a class="footnote-reference" href="#id7" id="id6">[2]</a> statement(语句), 它可以置于任何语句可以放置的位置.(与C/C++不同)</li>
<li>def生成了一个对象(函数对象),并将其赋值给一个名称(即函数名作为新的函数对象的一个引用)</li>
<li>return返回一个结果对象给调用者</li>
<li>参数按照 <strong>赋值</strong> (对象引用)来传值</li>
</ul>
<p>python的哲学:在Python编程中,我们编制对象 <strong>接口</strong>, 而非 <strong>数据类型</strong>.</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre>1
2
3
4
5
6</pre></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">times</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
    <span class="k">return</span> <span class="n">x</span><span class="o">*</span><span class="n">y</span>

<span class="n">times</span><span class="p">(</span><span class="mf">2</span><span class="p">,</span> <span class="mf">4</span><span class="p">)</span>     <span class="c"># return 8</span>
<span class="n">times</span><span class="p">(</span><span class="s">&quot;ok&quot;</span><span class="p">,</span> <span class="mf">4</span><span class="p">)</span>  <span class="c"># return &quot;okokokok&quot;</span>
<span class="c">#所谓的多态,即只要传入的参数支持 * 运算(接口),则函数times可用,而不用考虑数据类型.</span>
</pre></div>
</td></tr></table></div>
</div>
<table class="docutils footnote" frame="void" id="id7" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id6">[2]</a></td><td>statement在计算机中是指一段无返回值的指令.</td></tr>
</tbody>
</table>
</div>
<div class="section" id="id8">
<h2>python中的作用域<a class="headerlink" href="#id8" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>python中的作用域,即变量的作用范围.</p>
<p>Python变量作用域的查询规则(引用 X):</p>
<ul class="simple">
<li>首先在当前的local scope(function)中查找</li>
<li>其次在其中的嵌套函数中查找</li>
<li>然后在当前的global scope中(module file)</li>
<li>最后在built-in scope(module __builtint__)中查找</li>
</ul>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre>1
2
3
4
5
6
7
8</pre></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">f1</span><span class="p">():</span>
    <span class="n">x</span> <span class="o">=</span> <span class="mf">88</span>
    <span class="k">def</span> <span class="nf">f2</span><span class="p">():</span>
        <span class="k">print</span> <span class="n">x</span>
    <span class="k">return</span> <span class="n">f2</span>

<span class="n">action</span> <span class="o">=</span> <span class="n">f1</span><span class="p">()</span>
<span class="n">action</span><span class="p">()</span>        <span class="c"># will print 88</span>
</pre></div>
</td></tr></table></div>
<p class="last">在这个例子中, <tt class="docutils literal"><span class="pre">print</span> <span class="pre">x</span></tt> 中的引用x,会首先在f2()中查找,失败;
则在嵌套函数中查找,成功,此时x = 88.</p>
</div>
</div>
<div class="section" id="id9">
<h2>python中两种类型的类<a class="headerlink" href="#id9" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">python中有两种类型的类，即classic class和new-style class
它们在多重继承时的搜索顺序有较大差别，前者使用depth-first search
后者使用broad-first search</p>
</div>
<div class="section" id="classic-class">
<h3>classic class<a class="headerlink" href="#classic-class" title="永久链接至标题">¶</a></h3>
<blockquote>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">A</span><span class="p">:</span>
    <span class="n">attr</span> <span class="o">=</span> <span class="mf">1</span>
<span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
    <span class="k">pass</span>
<span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
    <span class="n">attr</span> <span class="o">=</span> <span class="mf">2</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">C</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="n">x</span> <span class="o">=</span> <span class="n">D</span><span class="p">()</span>
<span class="k">print</span> <span class="n">x</span><span class="o">.</span><span class="n">attr</span>    <span class="c">#此处应该返回 1,因为classic class使用的是深度优先搜索</span>
<span class="c"># 搜索顺序是：从左到右，深度优先搜索</span>
</pre></div>
</td></tr></table></div>
</blockquote>
</div>
<div class="section" id="new-style-class">
<h3>new-style class<a class="headerlink" href="#new-style-class" title="永久链接至标题">¶</a></h3>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>python中的new-style class是要么继承于build-in type，要么继承于object（任务的class都是object的子类）</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">A</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="n">attr</span> <span class="o">=</span> <span class="mf">1</span>
<span class="k">class</span> <span class="nc">B</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
    <span class="k">pass</span>
<span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="n">A</span><span class="p">):</span>
    <span class="n">attr</span> <span class="o">=</span> <span class="mf">2</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">C</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="n">x</span> <span class="o">=</span> <span class="n">D</span><span class="p">()</span>
<span class="k">print</span> <span class="n">x</span><span class="o">.</span><span class="n">attr</span>    <span class="c">#此处应该返回 2,因为new-style class使用的是广度优先搜索</span>
<span class="c">#搜索顺序是，从左到右（根据继承顺序），广度优先</span>

<span class="c">#如果想在new-style class中模拟classic class，可以直接指定对应类中的变量，可以这样：</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="n">B</span><span class="p">,</span> <span class="n">C</span><span class="p">):</span>
    <span class="n">attr</span> <span class="o">=</span> <span class="n">B</span><span class="o">.</span><span class="n">attr</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">D</span><span class="p">()</span>
<span class="k">print</span> <span class="n">x</span><span class="o">.</span><span class="n">attr</span>    <span class="c">#输出1</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="id10">
<h3>关于Python的伪私有变量（方法）<a class="headerlink" href="#id10" title="永久链接至标题">¶</a></h3>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>伪私有变量是指在Python的类定义中以两个_开头，不以两个_结束的变量或者方法，
在具体的使用中，其实例不能直接引用这些属性（所谓的 <em>伪</em> 是也），但是可通过
间接的方法，即_类名+变量名（无+号）</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre>1
2
3
4
5
6
7
8
9</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">test</span><span class="p">:</span>
    <span class="sd">&quot;&quot;&quot;To test the pseudoprivate attribute in python</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__x</span> <span class="o">=</span> <span class="s">&quot;zhutao&quot;</span>

<span class="n">c</span> <span class="o">=</span> <span class="n">test</span><span class="p">()</span>
<span class="k">print</span> <span class="n">c</span><span class="o">.</span><span class="n">__x</span> <span class="c">#will raise error</span>
<span class="k">print</span> <span class="n">c</span><span class="o">.</span><span class="n">_test__x</span> <span class="c">#will print &#39;zhutao&#39;</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="python-new-style">
<h3>python new-style类中的一些特别方法<a class="headerlink" href="#python-new-style" title="永久链接至标题">¶</a></h3>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">可能某些部分也适合classic class,会特别指出。</p>
</div>
<div class="section" id="instance-slots">
<span id="index-1"></span><h4>Instance slots<a class="headerlink" href="#instance-slots" title="永久链接至标题">¶</a></h4>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>用来限制可供访问的属性集，这样可以避免拼写错误,也可以节省访问时间（slot中的属性存于tuple中而非dict中）等。使用特殊属性 <tt class="docutils literal"><span class="pre">__slots__</span></tt>
在继承了含有slots声明的父类的子类中，如果没有显式声明，则无slot特性，而是使用dict.</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">limiter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="n">__slots__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;age&#39;</span><span class="p">,</span> <span class="s">&#39;name&#39;</span><span class="p">,</span> <span class="s">&#39;job&#39;</span><span class="p">]</span>

<span class="n">x</span> <span class="o">=</span> <span class="n">limiter</span><span class="p">()</span>
<span class="k">print</span> <span class="n">x</span><span class="o">.</span><span class="n">age</span> <span class="c">#error, 在使用前必须先赋值</span>
<span class="n">x</span><span class="o">.</span><span class="n">age</span> <span class="o">=</span> <span class="mf">4</span>
<span class="k">print</span> <span class="n">x</span><span class="o">.</span><span class="n">age</span> <span class="c">#ok</span>

<span class="n">x</span><span class="o">.</span><span class="n">sex</span> <span class="o">=</span> <span class="s">&quot;female&quot;</span>  <span class="c">#error, no such attribute</span>

<span class="k">class</span> <span class="nc">Subclass</span><span class="p">(</span><span class="n">limiter</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="n">e</span> <span class="o">=</span> <span class="n">Subclass</span><span class="p">()</span>
<span class="n">e</span><span class="o">.</span><span class="n">sex</span> <span class="o">=</span> <span class="s">&quot;female&quot;</span> <span class="c">#ok, subclass uses the dict, not slot</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="python-property">
<span id="index-2"></span><h4>python property<a class="headerlink" href="#python-property" title="永久链接至标题">¶</a></h4>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>property可以定义一个类的属性，很容易地定义getter, setter, deleter, 及docstring.
property也可使用 <a class="reference internal" href="#decorator"><em>python decorator</em></a> 来实现</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_x</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">def</span> <span class="nf">getter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_x</span>

    <span class="k">def</span> <span class="nf">setter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_x</span> <span class="o">=</span> <span class="n">value</span>

    <span class="k">def</span> <span class="nf">deleter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_x</span>

    <span class="c">#此处的参数名应与上面定义的部分相同，但具体使用什么方法名，不重要。</span>
    <span class="n">x</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">getter</span><span class="p">,</span> <span class="n">setter</span><span class="p">,</span> <span class="n">deleter</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>

    <span class="c"># 此处的getter, setter, deleter, docstring必须符合相应的协议（如参数列表，返回值等），</span>
    <span class="c">#如果docstring为None,则使用getter的docstring</span>

<span class="c">#也可以按照下面的方法来使用property</span>
<span class="k">class</span> <span class="nc">D</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_x</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">x</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>

        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_x</span>

    <span class="nd">@x</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">x</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">_x</span> <span class="o">=</span> <span class="n">value</span>

    <span class="nd">@x</span><span class="o">.</span><span class="n">deleter</span>
    <span class="k">def</span> <span class="nf">x</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>

        <span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_x</span>

<span class="c">#此类实现了与C相同的功能，不过采用的方式是不一样的，decorator的方法更加灵活有效。</span>
<span class="c">#如果对x没有声明相应的setter和deleter，则属性x为只读的属性（可用于模拟类似c++中的const）</span>
</pre></div>
</td></tr></table></div>
</div>
<p>参考：</p>
<blockquote>
<ol class="arabic simple">
<li><a class="reference external" href="http://docs.python.org/library/functions.html#property">python property</a></li>
<li><a class="reference external" href="http://docs.python.org/glossary.html#term-decorator">python decorator</a></li>
</ol>
</blockquote>
</div>
<div class="section" id="decorator">
<span id="index-3"></span><span id="id12"></span><h4>python decorator<a class="headerlink" href="#decorator" title="永久链接至标题">¶</a></h4>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>python decorator是函数的基础上执行一定的额外操作，通过&#64;wrapper形式的语法。
decorator返回的对象的唯一限制是：必须是callabe，所以function，class with __call__也是可以作为decorator</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">myDecorator</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;inside myDecorator.__init__()&quot;</span>
        <span class="n">f</span><span class="p">()</span> <span class="c">#Prove that function defination has completed</span>
    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;inside myDecorator.__call__()&quot;</span>

<span class="nd">@myDecorator</span>
<span class="k">def</span> <span class="nf">aFunction</span><span class="p">():</span>
    <span class="k">print</span> <span class="s">&quot;inside aFunction()&quot;</span>

<span class="k">print</span> <span class="s">&quot;Finished decorating aFunction()&quot;</span>
<span class="n">aFunction</span><span class="p">()</span>
<span class="c">#执行结果如下：</span>
<span class="c">#   inside myDecorator.__init__()</span>
<span class="c">#   inside aFunction()</span>
<span class="c">#   Finished decorating aFunction()</span>
<span class="c">#   inside myDecorator.__call__()</span>
</pre></div>
</td></tr></table></div>
</div>
<p>从上面的例子的输出的结果来看，需要注意的是：</p>
<blockquote>
<ul class="simple">
<li>myDecorator的构造函数(__init__)是在被修饰的函数位置执行</li>
<li>先会执行被修饰的函数的函数体</li>
<li>decorator会在构造函数中得到被修饰的函数对象</li>
</ul>
</blockquote>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>the &#64; is just a little syntax sugar meaning,
&#8220;pass a function object through another function and
assign the result to the original function.&#8221;</p>
<p class="last"><strong>You can apply code to other code with decorator</strong></p>
</div>
<p>另外一个例子：</p>
<blockquote>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">EntryExit</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>

    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwag</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;Enter </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="o">.</span><span class="n">__name__</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwag</span><span class="p">)</span>
        <span class="k">print</span> <span class="s">&quot;Exit </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="o">.</span><span class="n">__name__</span>

    <span class="nd">@EntryExit</span>
    <span class="k">def</span> <span class="nf">sum3</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
        <span class="k">print</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>

    <span class="n">sum3</span><span class="p">(</span><span class="mf">2</span><span class="p">,</span><span class="mf">3</span><span class="p">)</span>

<span class="c">#输出为：</span>
<span class="c">#   Enter sum3</span>
<span class="c">#   5</span>
<span class="c">#   Exit sum3</span>

<span class="c">#因为function也是callable，所以上面的例子可改为：</span>
<span class="k">def</span> <span class="nf">entryexit</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">new_f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwag</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;Enter </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">f</span><span class="o">.</span><span class="n">__name__</span>
        <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwag</span><span class="p">)</span>
        <span class="k">print</span> <span class="s">&quot;Exit </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">f</span><span class="o">.</span><span class="n">__name__</span>
    <span class="k">return</span> <span class="n">new_f</span>

<span class="nd">@entryexit</span>
<span class="k">def</span> <span class="nf">sum4</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span>
</pre></div>
</td></tr></table></div>
</blockquote>
<p>带参数的decorator的例子</p>
<blockquote>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">EntryExit</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwag</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">args</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">k</span><span class="p">,</span><span class="n">v</span> <span class="ow">in</span> <span class="n">kwag</span><span class="o">.</span><span class="n">iteritems</span><span class="p">():</span>
            <span class="nb">setattr</span><span class="p">(</span><span class="n">EntryExit</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
        <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">arg</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
            <span class="k">print</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
            <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">arg</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">wrapper</span>

<span class="nd">@EntryExit</span><span class="p">(</span><span class="s">&quot;zhutao&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">zhutao</span><span class="p">(</span><span class="n">age</span><span class="o">=</span><span class="mf">24</span><span class="p">):</span>
    <span class="k">print</span> <span class="n">age</span>

<span class="c"># will print: [&#39;zhutao&#39;]\n24</span>
</pre></div>
</td></tr></table></div>
</blockquote>
<p>同样也适用于函数的decorator
所以decorator可以方便地在一个函数之前或者之后加入相应的操作处理，类似于AOP.
参考：</p>
<blockquote>
<ol class="arabic simple">
<li><a class="reference external" href="http://www.artima.com/weblogs/viewpost.jsp?thread=240808">Decorators I: Introduction to Python Decorators</a></li>
<li><a class="reference external" href="http://wiki.python.org/moin/PythonDecoratorLibrary">PythonDecoratorLibrary</a></li>
</ol>
</blockquote>
</div>
</div>
</div>
<div class="section" id="abstract-superclass">
<span id="index-4"></span><h2>abstract superclass 抽象基类<a class="headerlink" href="#abstract-superclass" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>抽象基类是指期待其部分行为由其子类来实现的基类（父类），如：</p>
<div class="last highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></td><td class="code"><div class="highlight"><pre><span class="c"># Super中无action的实现，它期待其子类实现</span>
<span class="k">class</span> <span class="nc">Super</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;in Super.method&quot;</span>
    <span class="k">def</span> <span class="nf">delegate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">action</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">Provider</span><span class="p">(</span><span class="n">Super</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">action</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="c"># do something here</span>
        <span class="k">print</span> <span class="s">&quot;in Provider.action&quot;</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="callback-function">
<span id="index-5"></span><h2>回调函数Callback function<a class="headerlink" href="#callback-function" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p>使用回调函数来保持状态信息，可能是Python中最好的方法（相比于global变量，嵌套函数，可变类型等）。</p>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Callback</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">color</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="n">color</span>
    <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;turn&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">color</span>
<span class="n">cb1</span> <span class="o">=</span> <span class="n">Callback</span><span class="p">(</span><span class="s">&quot;blue&quot;</span><span class="p">)</span>
<span class="n">cb2</span> <span class="o">=</span> <span class="n">Callback</span><span class="p">(</span><span class="s">&quot;red&quot;</span><span class="p">)</span>

<span class="n">B1</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="n">command</span> <span class="o">=</span> <span class="n">cb1</span><span class="p">)</span>  <span class="c">#Register handlers</span>
<span class="n">B2</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="n">command</span> <span class="o">=</span> <span class="n">cb2</span><span class="p">)</span>  <span class="c">#Register handlers</span>
<span class="c">#那么在响应相应的事件时，会调用回调函数（类）cb1(),cb2()，从而得到不同的处理</span>
</pre></div>
</td></tr></table></div>
<p>常用的三种保持状态信息的方法：</p>
<ul class="simple">
<li>上述的方法</li>
<li>使用缺省的lambda函数，如 <tt class="docutils literal"><span class="pre">cb3</span> <span class="pre">=</span> <span class="pre">(lambda</span> <span class="pre">color='red':'turn'</span> <span class="pre">+</span> <span class="pre">color)</span></tt></li>
<li>使用类中的bound method，例如：</li>
</ul>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">Callback</span><span class="p">:</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">color</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">color</span> <span class="o">=</span> <span class="n">color</span>
    <span class="k">def</span> <span class="nf">changeColor</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">print</span> <span class="s">&quot;turn&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">color</span>

<span class="n">cb1</span> <span class="o">=</span> <span class="n">Callback</span><span class="p">(</span><span class="s">&quot;blue&quot;</span><span class="p">)</span>
<span class="n">cb2</span> <span class="o">=</span> <span class="n">Callback</span><span class="p">(</span><span class="s">&quot;red&quot;</span><span class="p">)</span>

<span class="n">B1</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="n">cb1</span><span class="o">.</span><span class="n">changeColor</span><span class="p">)</span>
<span class="n">B2</span> <span class="o">=</span> <span class="n">Button</span><span class="p">(</span><span class="n">command</span><span class="o">=</span><span class="n">cb2</span><span class="o">.</span><span class="n">changeColor</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
<p class="last">通常第三种方法没有第一种常用。</p>
</div>
</div>
<div class="section" id="index-6">
<span id="id13"></span><h2>异常处理总结<a class="headerlink" href="#index-6" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">使用异常，可以一步跳到异常处理部分，终止所有suspended函数。
所以可以认为：异常是一各 <em>super-goto</em> .</p>
</div>
<div class="section" id="id14">
<h3>异常处理的作用<a class="headerlink" href="#id14" title="永久链接至标题">¶</a></h3>
<p>在Python中异常处理的主要作用包括：</p>
<blockquote>
<ol class="arabic">
<li><p class="first">错误处理</p>
</li>
<li><dl class="first docutils">
<dt>事件通知</dt>
<dd><p class="first last">可以使用异常来代替flag来进行事件通知。</p>
</dd>
</dl>
</li>
<li><p class="first">特殊情形处理</p>
</li>
<li><dl class="first docutils">
<dt>终止动作</dt>
<dd><p class="first last">使用try..finally可以在即使出现异常的情况下，也能够执行某些既定的终止动作。</p>
</dd>
</dl>
</li>
<li><p class="first">特殊的控制流</p>
</li>
</ol>
</blockquote>
</div>
<div class="section" id="id15">
<h3>具体的语法<a class="headerlink" href="#id15" title="永久链接至标题">¶</a></h3>
<blockquote>
<ol class="arabic">
<li><dl class="first docutils">
<dt>try..except结构</dt>
<dd><p class="first">工作原理：当一个try开始后，Python标记当前的程序上下文(context），所以当有异常
发生时，可以返回。在try中的block先执行，如果：</p>
<ul class="last simple">
<li>如果在try的block的执行过程发生异常，python则跳回到try，并且执行第一个匹配异常
的except block中的操作。控制在整个try后继续进行。</li>
<li>如果在try的block中发生异常，并且没有相应的except匹配，则异常得以传播（传播到上一个
try或者进程的顶层）</li>
<li>如果在try的block中无异常产生，则Python会执行else(如果有的话）中的语句
然后控制在整个try后继续进行。</li>
</ul>
</dd>
</dl>
</li>
<li><dl class="first docutils">
<dt>try..(except..else..)..finally..结构</dt>
<dd><p class="first">finally后的block总会得以执行，无论是否有异常产生。</p>
<p class="last"><em>to serve as the cleanup action</em></p>
</dd>
</dl>
</li>
<li><p class="first">raise产生异常</p>
</li>
</ol>
</blockquote>
</div>
<div class="section" id="id16">
<h3>相关的代码<a class="headerlink" href="#id16" title="永久链接至标题">¶</a></h3>
<p>try..finally..</p>
<blockquote>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">MyException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">def</span> <span class="nf">action</span><span class="p">(</span><span class="nb">file</span><span class="p">):</span>
    <span class="k">raise</span> <span class="n">MyException</span><span class="p">()</span>

<span class="nb">file</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">&quot;hello.txt&quot;</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
    <span class="n">action</span><span class="p">(</span><span class="nb">file</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
    <span class="nb">file</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>                        <span class="c">#无论是否出现异常，文件都会被关闭</span>
    <span class="k">print</span> <span class="s">&quot;file has been closed safely.&quot;</span>
</pre></div>
</td></tr></table></div>
</blockquote>
<p>raise with extra data</p>
<blockquote>
<div class="highlight-python"><table class="highlighttable"><tr><td class="linenos"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">myException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
    <span class="k">pass</span>

<span class="k">def</span> <span class="nf">raise1</span><span class="p">():</span>
    <span class="k">raise</span> <span class="n">myException</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span>
<span class="k">def</span> <span class="nf">raise2</span><span class="p">():</span>
    <span class="k">raise</span> <span class="n">myException</span>

<span class="k">def</span> <span class="nf">tryer</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">func</span><span class="p">()</span>
    <span class="k">except</span> <span class="n">myException</span><span class="p">,</span> <span class="n">extradata</span><span class="p">:</span>
        <span class="k">print</span> <span class="s">&quot;got this:&quot;</span><span class="p">,</span> <span class="n">extradata</span>
<span class="n">tryer</span><span class="p">(</span><span class="n">raise1</span><span class="p">)</span>   <span class="c">#print: got this: hello</span>
<span class="n">tryer</span><span class="p">(</span><span class="n">raise2</span><span class="p">)</span>   <span class="c">#print: got this:</span>
</pre></div>
</td></tr></table></div>
</blockquote>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="index.html">內容目录</a></h3>
            <ul>
<li><a class="reference external" href="">learning python学习心得</a><ul>
<li><a class="reference external" href="#id1">到主页的链接</a></li>
<li><a class="reference external" href="#id3">关于learning python</a></li>
<li><a class="reference external" href="#import">关于import</a></li>
<li><a class="reference external" href="#python-type-hierarchies">python类型继承关系(type hierarchies)</a></li>
<li><a class="reference external" href="#python">python中的函数</a></li>
<li><a class="reference external" href="#id8">python中的作用域</a></li>
<li><a class="reference external" href="#id9">python中两种类型的类</a><ul>
<li><a class="reference external" href="#classic-class">classic class</a></li>
<li><a class="reference external" href="#new-style-class">new-style class</a></li>
<li><a class="reference external" href="#id10">关于Python的伪私有变量（方法）</a></li>
<li><a class="reference external" href="#python-new-style">python new-style类中的一些特别方法</a><ul>
<li><a class="reference external" href="#instance-slots">Instance slots</a></li>
<li><a class="reference external" href="#python-property">python property</a></li>
<li><a class="reference external" href="#decorator">python decorator</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference external" href="#abstract-superclass">abstract superclass 抽象基类</a></li>
<li><a class="reference external" href="#callback-function">回调函数Callback function</a></li>
<li><a class="reference external" href="#index-6">异常处理总结</a><ul>
<li><a class="reference external" href="#id14">异常处理的作用</a></li>
<li><a class="reference external" href="#id15">具体的语法</a></li>
<li><a class="reference external" href="#id16">相关的代码</a></li>
</ul>
</li>
</ul>
</li>
</ul>

            <h4>上一个主题</h4>
            <p class="topless"><a href="syntax.html"
                                  title="上一章">python一些重要但不熟悉的语法</a></p>
            <h4>下一个主题</h4>
            <p class="topless"><a href="disadvantage.html"
                                  title="下一章">python的缺点</a></p>
            <h3>本页</h3>
            <ul class="this-page-menu">
              <li><a href="_sources/learning-python.txt"
                     rel="nofollow">显示源代码</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>快速搜索</h3>
              <form class="search" action="search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="搜索" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              输入相关的模块，术语，类或者函数名称进行搜索
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="disadvantage.html" title="python的缺点"
             >下一页</a> |</li>
        <li class="right" >
          <a href="syntax.html" title="python一些重要但不熟悉的语法"
             >上一页</a> |</li>
        <li><a href="index.html">python学习笔记</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; 版权所有 2009, zhutao.
      使用 <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
    </div>
  </body>
</html>